package org.rambadger.command.auth;


import org.axonframework.eventhandling.annotation.EventHandler;
import org.axonframework.eventhandling.replay.ReplayAware;
import org.mongojack.JacksonDBCollection;
import org.rambadger.command.event.PlatformRoleChanged;
import org.rambadger.command.event.SystemRoleChanged;
import org.rambadger.command.event.UserPasswordChanged;
import org.rambadger.command.event.UserRegistered;

/**
 * Auth listener is an Axon EventListener that is responsible for maintaining the information on user roles, as well as the password hash.
 *
 * @see AuthUser
 */
public class AuthListener implements ReplayAware {
    private JacksonDBCollection<AuthUser, String> users;

    /**
     * Instantiates a new AuthListener
     *
     * @param users wrapped {@link com.mongodb.DBCollection} collection
     * <p>
     * Use {@link org.rambadger.command.axon.MongoBundle#getWrappedCollection(Class, Class)} to get the wrapped collection.
     * </p>
     */
    public AuthListener(JacksonDBCollection<AuthUser, String> users) {
        this.users = users;
    }

    @Override
    public void beforeReplay() {
        users.drop();
    }

    @Override
    public void afterReplay() {
    }

    @EventHandler void on(UserRegistered event) {
        AuthUser user = new AuthUser(event.getUsername(), event.getPasswordHash());
        users.insert(user);
    }

    @EventHandler void on(UserPasswordChanged event) {
        AuthUser user = users.findOneById(event.getUsername());
        user.setPasswordHash(event.getNewPasswordHash());
        users.save(user);
    }

    @EventHandler void on(PlatformRoleChanged.PlatformRoleGranted event) {
        AuthUser user = users.findOneById(event.getUsername());
        user.addPlatformRole(event.getPlatform(), event.getRole());
        users.save(user);
    }

    @EventHandler void on(PlatformRoleChanged.PlatformRoleRevoked event) {
        AuthUser user = users.findOneById(event.getUsername());
        user.removePlatformRole(event.getPlatform(), event.getRole());
        users.save(user);
    }


    @EventHandler void on(SystemRoleChanged.AccessGranted event) {
        AuthUser user = users.findOneById(event.getUsername());
        user.setHasAccess(true);
        users.save(user);
    }

    @EventHandler void on(SystemRoleChanged.AccessRevoked event) {
        AuthUser user = users.findOneById(event.getUsername());
        user.setHasAccess(false);
        users.save(user);
    }


    @EventHandler void on(SystemRoleChanged.AdminGranted event) {
        AuthUser user = users.findOneById(event.getUsername());
        user.setHasSystemAdmin(true);
        users.save(user);
    }

    @EventHandler void on(SystemRoleChanged.AdminRevoked event) {
        AuthUser user = users.findOneById(event.getUsername());
        user.setHasSystemAdmin(false);
        users.save(user);
    }
}
